package net.com.sunkey.messagehandler;

import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.Map.Entry;

import net.com.sunkey.protobuf.PluginRequest.PluginRequestData;
import net.com.sunkey.protobuf.PluginResponse.PluginResponseData;
import net.com.sunkey.protobuf.PropertyData.Property;
import net.com.sunkey.protobuf.Protocol;
import net.com.sunkey.serverlogic.Plugin;
import net.com.sunkey.serverlogic.PluginData;
import net.com.sunkey.serverlogic.Server;
import net.com.sunkey.serverlogic.User;

/**
 * @author kohachiro
 *
 */
public class PluginRequestHandler {
	/**
	 * 
	 */
	public static int invoke(Object obj, Object channel)  throws Exception {
		System.out.println("["+channel.hashCode()+"]["+Protocol.MessageHandler.PluginRequest_VALUE+"]PluginRequest");		
		PluginRequestData data=(PluginRequestData)obj;				
		if (!data.hasName())
			return ServerErrorResponseHandler.invoke(Protocol.ReturnStatus.STATUS_PLUGIN_NOT_FOUND_VALUE, channel);
		if (!data.hasAction())
			return ServerErrorResponseHandler.invoke(Protocol.ReturnStatus.STATUS_PLUGIN_ACTION_NOT_FOUND_VALUE, channel);		
		Plugin plugin=Server.getPlugin(data.getName());
		if (plugin==null)
			return ServerErrorResponseHandler.invoke(Protocol.ReturnStatus.STATUS_PLUGIN_NOT_FOUND_VALUE, channel);
		User user=User.get(channel);
		
		Class<?> clazz=plugin.getClass();
		PluginData result;
		try {
			//result = (List<String>) Reflection.invokeMethod(plugin, data.getAction(), new Object[]{data,user});
			Method method = clazz.getMethod(data.getAction(),new Class[] { PluginRequestData.class,User.class });
			result = (PluginData) method.invoke(plugin, new Object[]{data,user});
		} catch (java.lang.NoSuchMethodException e) {
			result=plugin.invoke(data, user);
		}
		PluginResponseData.Builder builder=PluginResponseData.newBuilder();
		builder.setName(data.getName());
		builder.setAction(data.getAction());

		System.out.println("PluginResponse:"+data.getName()+"."+data.getAction());
		
		Property.Builder propertyBuilder;
		Entry<String, String> entry;
		for (Iterator<Entry<String, String>> it = result.getProperties().entrySet().iterator();it.hasNext();){
			entry=it.next();
			propertyBuilder=Property.newBuilder();
			propertyBuilder.setName(entry.getKey());
			propertyBuilder.setValue(entry.getValue());
			builder.addProperties(propertyBuilder);
		}

		PluginResponseData message=builder.build();		
		PluginResponseHandler.invoke(ByteBuffer.wrap(message.toByteArray()), user.getChannel());
		return Protocol.MessageHandler.PluginRequest_VALUE;		
	}

}
